package com.ygqh.baby.service.impl;

import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.mapper.YgFocusMapper;
import com.ygqh.baby.model.YgFocusModel;
import com.ygqh.baby.po.YgFocus;
import com.ygqh.baby.po.YgFocusExample;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.YgFocusService;
import com.ygqh.baby.utils.DateConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class YgFocusServiceImpl implements YgFocusService {

    @Autowired
    private YgFocusMapper ygFocusMapper;
    @Autowired
    private RedisDao redisDao;

    @Override
    public List<YgFocus> find() {
        YgFocusExample example = new YgFocusExample();
        example.createCriteria().andStatusNotEqualTo(DataStatus.Valid.name());
        return ygFocusMapper.selectByExample(example);
    }

    @Override
    public int findCount() {
        YgFocusExample example = new YgFocusExample();
        example.createCriteria().andStatusNotEqualTo(DataStatus.Delete.name());
        return ygFocusMapper.countByExample(example);
    }

    @Override
    public YgFocus findById(Long id) {
        return ygFocusMapper.selectByPrimaryKey(id);
    }


    @Override
    public int save(YgFocus ygFocus) {
        int i = ygFocusMapper.insertSelective(ygFocus);
        resetCache(ygFocus.getId(), ygFocus.getFocusType(), ygFocus.getPageKey());
        return i;
    }

    @Override
    public int update(YgFocus ygFocus) {
        int i = ygFocusMapper.updateByPrimaryKeySelective(ygFocus);
        resetCache(ygFocus.getId(), ygFocus.getFocusType(), ygFocus.getPageKey());
        return i;
    }

    @Override
    public ResultSet<YgFocus> search(QueryInfo queryInfo, String q, FocusType focusType, PageKey pageKey) {
        List<YgFocus> list = ygFocusMapper.selectSuper(queryInfo, q, focusType == null ? null : focusType.name(), pageKey == null ? null : pageKey.name());
        int count = ygFocusMapper.countSuper(q, focusType == null ? null : focusType.name(), pageKey == null ? null : pageKey.name());
        return new ResultSet<>(count, list);
    }

    @Override
    public List<YgFocusModel> searchModel(FocusType focusType, String pageKey) {
        return ygFocusMapper.selectModelSuper(focusType.name(), DateConvertUtils.formatToDate(new Date(), "yyyy-MM-dd"), pageKey);
    }

    private final static String REDIS_FOCUS_KEY_PREFIX = "focus_%s_%s";
    private final static int REDIS_FOCUS_EXPIRE = 60 * 60 * 1000;

    @Override
    public List<YgFocusModel> searchModelByCache(FocusType focusType, String... pageKey) {
        if (pageKey == null || pageKey.length == 0) {
            return Collections.emptyList();
        }
        List<YgFocusModel> list = new ArrayList<>();
        for (String key : pageKey) {
            List<YgFocusModel> modelList = doGetFromCache(focusType, key);
            list.addAll(modelList);
        }
        return list.stream().filter(YgFocusModel::valid).collect(Collectors.toList());
    }


    private void resetCache(Long focusId, String sourceFocusType, String sourcePageKey) {
        YgFocus ygFocus = ygFocusMapper.selectByPrimaryKey(focusId);
        if (ygFocus.getFocusType().equals(sourceFocusType) && ygFocus.getPageKey().equals(sourcePageKey)) {
            doSetCache(ygFocus.getFocusType(), ygFocus.getPageKey());
        } else {
            doSetCache(sourceFocusType, ygFocus.getPageKey());
        }
    }

    private void doSetCache(String focusType, String pageKey) {
        List<YgFocusModel> modelList = this.searchModel(FocusType.valueOf(focusType), pageKey);
        if (modelList == null) {
            modelList = Collections.emptyList();
        }
        String cacheKey = String.format(REDIS_FOCUS_KEY_PREFIX, focusType, pageKey);
        doSetCache(modelList, cacheKey);
    }

    private void doSetCache(List<YgFocusModel> modelList, String cacheKey) {
        if (modelList == null) {
            modelList = Collections.emptyList();
        }
        redisDao.set(cacheKey, JSON.toJSONString(modelList), REDIS_FOCUS_EXPIRE);
    }


    private List<YgFocusModel> doGetFromCache(FocusType focusType, String pageKey) {
        String cacheKey = String.format(REDIS_FOCUS_KEY_PREFIX, focusType.name(), pageKey);
        String res = redisDao.get(cacheKey);
        List<YgFocusModel> modelList;
        if (StringUtil.isBlank(res)) {
            modelList = this.searchModel(focusType, pageKey);
            doSetCache(modelList, cacheKey);
        } else {
            modelList = JSON.parseArray(res, YgFocusModel.class);
        }
        return modelList;
    }

    @Override
    public int saveOrUpdate(YgFocus ygFocus) {
        int r;
        if (ygFocus.getId() != null) {
            r = this.update(ygFocus);
        } else {
            r = this.save(ygFocus);
        }
        return r;
    }

    @Override
    public List<YgFocusModel> searchYiJiDianModel(FocusType focus) {

        return ygFocusMapper.selectYiJiaDianModel(focus, DateConvertUtils.formatToDate(new Date(), "yyyy-MM-dd"));
    }


}

